package org.leviatan.dataharbour.gui.swingcomponents.views;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;

import org.leviatan.dataharbour.core.model.PersistenceResource;
import org.leviatan.dataharbour.core.model.impl.HibernatePersistenceResourceImpl;
import org.leviatan.dataharbour.gui.RuntimeContext;
import org.leviatan.dataharbour.gui.swingmodels.TreeMdlPersistenceResource;
import org.leviatan.dataharbour.gui.swingmodels.TreeNodeMdlPersistenceResource;

/**
 * 
 * @author Leviatan
 *
 */
public class PersistenceResourceDetailPanel extends JPanel {

	private static final long serialVersionUID = -437029774930399182L;

	private JLabel lblTitle;
	
	private JLabel lblId;
	private JLabel lblIdTxt;
	
	private JLabel lblName;
	private JTextField txtName;
	
	private JLabel lblType;
	private JComboBox cmbType;
	private String[] cmbChoices = {"Hibernate (generic)"};
	
	private JLabel lblChooseFile;
	private JTextField txtChooseFile;
	private JButton butChooseFile;
	
	private JButton butUpdate;
	private JButton butReset;

	private JPanel butPanel;
	
	public PersistenceResourceDetailPanel() {
		super();
		this.init();
	}
	
	private void init() {
		this.setLayout(new GridBagLayout());
		
		this.lblTitle = new JLabel("Edit details for persistence resource");
		
		this.lblId = new JLabel("Id:");
		this.lblIdTxt = new JLabel();
		
		this.lblName = new JLabel("Name:");
		this.txtName = new JTextField();
		this.txtName.setColumns(20);
		
		this.lblType = new JLabel("Type:");
		this.cmbType = new JComboBox(cmbChoices);
		
		this.lblChooseFile = new JLabel("Hibernate Configuration file:");
		this.txtChooseFile = new JTextField();
		this.txtChooseFile.setColumns(40);
		this.butChooseFile = new JButton("Pick file...");
		
		this.butUpdate = new JButton("Update");
		this.butReset = new JButton("Reset");
		
		GridBagConstraints lblTitleC = new GridBagConstraints();
		
		GridBagConstraints lblIdC = new GridBagConstraints();
		GridBagConstraints lblIdTxtC = new GridBagConstraints();
		
		GridBagConstraints lblNameC = new GridBagConstraints();
		GridBagConstraints txtNameC = new GridBagConstraints();
		
		GridBagConstraints lblTypeC = new GridBagConstraints();
		GridBagConstraints cmbTypeC = new GridBagConstraints();
		
		GridBagConstraints lblChooseFileC = new GridBagConstraints();
		GridBagConstraints txtChooseFileC = new GridBagConstraints();
		GridBagConstraints butChooseFileC = new GridBagConstraints();
		
		GridBagConstraints butPanelC = new GridBagConstraints();
		
		lblTitleC.anchor = GridBagConstraints.NORTHWEST;
		lblTitleC.gridwidth = 2;
		lblTitleC.gridx = 0;
		lblTitleC.gridy = 0;
		lblTitleC.insets = new Insets(20,5,20,5);
		
		lblIdC.anchor = GridBagConstraints.NORTHWEST;
		//lblIdC.fill = GridBagConstraints.BOTH;
		lblIdC.gridx = 0;
		lblIdC.gridy = 1;
		lblIdC.insets = new Insets(5,5,5,5);
		
		lblIdTxtC.anchor = GridBagConstraints.WEST;
		lblIdTxtC.fill = GridBagConstraints.NONE;
		lblIdTxtC.gridx = 1;
		lblIdTxtC.gridy = 1;
		lblIdTxtC.insets = new Insets(5,5,5,5);
		
		lblNameC.anchor = GridBagConstraints.WEST;
		lblNameC.fill = GridBagConstraints.NONE;
		lblNameC.gridx = 0;
		lblNameC.gridy = 2;
		lblNameC.insets = new Insets(5,5,5,5);
		
		txtNameC.anchor = GridBagConstraints.WEST;
		txtNameC.fill = GridBagConstraints.NONE;
		txtNameC.gridx = 1;
		txtNameC.gridy = 2;
		txtNameC.insets = new Insets(5,5,5,5);
		
		lblTypeC.anchor = GridBagConstraints.WEST;
		lblTypeC.fill = GridBagConstraints.NONE;
		lblTypeC.gridx = 0;
		lblTypeC.gridy = 3;
		lblTypeC.insets = new Insets(5,5,5,5);
		
		cmbTypeC.anchor = GridBagConstraints.WEST;
		cmbTypeC.fill = GridBagConstraints.NONE;
		cmbTypeC.gridx = 1;
		cmbTypeC.gridy = 3;
		cmbTypeC.insets = new Insets(5,5,5,5);
		
		lblChooseFileC.fill = GridBagConstraints.NONE;
		lblChooseFileC.anchor = GridBagConstraints.WEST;
		lblChooseFileC.gridx = 0;
		lblChooseFileC.gridy = 4;
		lblChooseFileC.insets = new Insets(5,5,5,5);
		
		txtChooseFileC.fill = GridBagConstraints.NONE;
		txtChooseFileC.anchor = GridBagConstraints.WEST;
		txtChooseFileC.gridx = 1;
		txtChooseFileC.gridy = 4;
		txtChooseFileC.insets = new Insets(5,5,0,5);
		
		butChooseFileC.fill = GridBagConstraints.NONE;
		butChooseFileC.anchor = GridBagConstraints.WEST;
		butChooseFileC.gridx = 1;
		butChooseFileC.gridy = 5;
		butChooseFileC.insets = new Insets(0,5,10,5);
		
		butPanelC.anchor = GridBagConstraints.WEST;
		butPanelC.fill = GridBagConstraints.NONE;
		butPanelC.gridwidth = 2;
		butPanelC.gridx = 0;
		butPanelC.gridy = 6;
		butPanelC.weighty = 1.0;
		butPanelC.weightx = 1.0;
		//butPanelC.ipadx = 50;
		//butPanelC.insets = new Insets(5,5,5,5);
		
		
		this.add(lblTitle, lblTitleC);
		
		this.add(lblId, lblIdC);
		this.add(lblIdTxt, lblIdTxtC);
		
		this.add(lblName, lblNameC);
		this.add(txtName, txtNameC);
		
		this.add(lblType, lblTypeC);
		this.add(cmbType, cmbTypeC);
		
		this.add(lblChooseFile, lblChooseFileC);
		this.add(butChooseFile, butChooseFileC);
		this.add(txtChooseFile, txtChooseFileC);
		
		this.add(getButtonPanel(), butPanelC);
		
		// add listeners
		this.butChooseFile.addMouseListener(new MouseAdapter() {
			
			public void mouseClicked(MouseEvent e) {
				// bring up the file choose dialog
				final JFileChooser fc = new JFileChooser();
				fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
				int response = fc.showOpenDialog(PersistenceResourceDetailPanel.this);
				
				if (response == JFileChooser.APPROVE_OPTION) {
		            File file = fc.getSelectedFile();
		            PersistenceResourceDetailPanel.this.txtChooseFile.setText(file.getPath());
		        }
			}
			
		});
		
		this.butReset.addMouseListener(new MouseAdapter() {
			
			public void mouseClicked(MouseEvent e) {
				PersistenceResourceDetailPanel.this.updateData(
						RuntimeContext.dataHarbourService.getPersistenceResource(
								PersistenceResourceDetailPanel.this.getSelectedPersResId()));
			}
			
		});
		
		this.butUpdate.addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {
				String id = lblIdTxt.getText();
				String name = txtName.getText();
				String type = cmbType.getSelectedItem().toString().trim();
				if (type.equals("Hibernate (generic)")) {
					
					String filePath = txtChooseFile.getText().trim();
					File confFile = new File(filePath);
					if (!confFile.canRead()) {
						System.out.println("error - cannot read specified file.");
						return;
					}
					//XMLIO.getInstance().readXMLFile(filePath);
					
					FileReader fr = null;
					try {
						fr = new FileReader(confFile);
					} catch (FileNotFoundException e1) {
						System.out.println("error - cannot read specified file.");
						e1.printStackTrace();
						return;
					}
					BufferedReader br = new BufferedReader(fr);
					
					String confString = "";
					String tmpStr = "";
					while (tmpStr != null) {
						try {
							confString += tmpStr + "\n";
							tmpStr = br.readLine();
						} catch (IOException e1) {
							e1.printStackTrace();
						}
					}
				
					RuntimeContext.dataHarbourService.updateHibernatePersistenceResource(id, name, confString);
				}
				else
					RuntimeContext.dataHarbourService.updatePersistenceResource(id, name);
				//String pId = PersistenceResourceDetailPanel.this.getSelectedPersResId();
				
				
				RuntimeContext.dataHarbourService.savePersistenceResources();
				
				((TreeMdlPersistenceResource) RuntimeContext.persResTree.getModel()).reload();
				
				TreeNodeMdlPersistenceResource nodeMdl = ((TreeMdlPersistenceResource)
						RuntimeContext.persResTree.getModel()).getNodeModel(id);
				
				RuntimeContext.persResTree.setSelectionPath(new TreePath(nodeMdl.getPath()));
			}
			
		});
	}
	
	private String getSelectedPersResId() {
		
		DefaultMutableTreeNode selectedNode = 
			(DefaultMutableTreeNode) RuntimeContext.persResTree.getLastSelectedPathComponent();

		if (selectedNode == null) return null;
	
		TreeNodeMdlPersistenceResource persNodeModel = 
			(TreeNodeMdlPersistenceResource) selectedNode.getUserObject();
		
		return persNodeModel.getId();
	}
	
	public void updateData(PersistenceResource p) {
		
		this.lblIdTxt.setText(p.getId());
		this.txtName.setText(p.getName());
		if (p.getType().equals("hibernate")) {
			HibernatePersistenceResourceImpl hpr = (HibernatePersistenceResourceImpl) p;
			if (hpr.getConfString() != null && !hpr.getConfString().isEmpty()
					&& !hpr.getConfString().equals(""))
				this.txtChooseFile.setText("<hibernate configuration file exists>");
			else
				this.txtChooseFile.setText("<no file set>");
			this.cmbType.setSelectedItem("Hibernate (generic)");
		} else if (p.getType().equals("db")) {
			this.txtChooseFile.setText("<no file set for db type>");
		} else if (p.getType().equals("file")) {
			this.txtChooseFile.setText("<no file can be set for file system type>");
		}
	}
	
	private JPanel getButtonPanel() {
		this.butPanel = new JPanel();
		
		GridBagConstraints butUpdateC = new GridBagConstraints();
		GridBagConstraints butResetC = new GridBagConstraints();
		
		butUpdateC.fill = GridBagConstraints.NONE;
		butUpdateC.anchor = GridBagConstraints.WEST;
		//butUpdateC.insets = new Insets(10, 20, 10, 20);
		//butUpdateC.gridwidth = 1;
		//butUpdateC.ipady = 0;
		//butUpdateC.ipadx = 0;
		butUpdateC.gridx = 0;
		butUpdateC.gridy = 0;
		
		butResetC.anchor = GridBagConstraints.WEST;
		butResetC.fill = GridBagConstraints.NONE;
		//butResetC.insets = new Insets(10, 20, 10, 20);
		//butResetC.gridwidth = 1;
		//butResetC.ipady = 0;
		//butResetC.ipadx = 0;
		butResetC.gridx = 1;
		butResetC.gridy = 0;
		butResetC.weightx = 1.0;
		
		this.butPanel.add(this.butUpdate, butUpdateC);
		this.butPanel.add(this.butReset, butResetC);
		
		return this.butPanel;
	}
	
}
